﻿using System;
using System.Collections.Generic;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Web.Http;
using System.Web.Mvc.Html;
using WebServiceTMS.Helpers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;

namespace WebServiceTMS.Controllers
{
    public class UserController : ApiController
    {
        //GET api/User/GetAllUsers
        [HttpGet]
        [ActionName("GetAllUsers")]
        public HttpResponseMessage GetAllUsers(HttpRequestMessage request)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var query = from u in context.Users
                                select new TMSUser
                                {
                                    Id = SqlFunctions.StringConvert((double)u.Id).Trim(),
                                    Name = u.Name,
                                    Surname = u.Surname,
                                    Phone = u.Phone,
                                    Email = u.Email,
                                    Login = u.Login,
                                    Status = u.Status
                                };
                    var userList = query.ToArray();
                    if (userList.Any())
                    {
                        for (var i = 0; i < userList.Count(); i++)
                        {
                            userList[i].Id = TMSCryptography.Encrypt(userList[i].Id);
                        }
                        var jsonResponse = JsonConvert.SerializeObject(userList);
                        return HttpResponseHelper.CreateHttpResponse("success", jsonResponse);
                    }
                    return HttpResponseHelper.CreateHttpResponse("success", "[]");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/User/RegistrateNewUser
        [HttpPost]
        [ActionName("RegistrateNewUser")]
        public HttpResponseMessage RegistrateNewUser(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;

                var userObject = JObject.Parse(jsonContent);

                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string userId = null;
                    bool isSuccessUserId = tmp.TryGetValue("UserId", out userId);
                    string name = null;
                    bool isSuccessName = tmp.TryGetValue("Name", out name);
                    string surname = null;
                    bool isSuccessSurname = tmp.TryGetValue("Surname", out surname);
                    string phone = null;
                    bool isSuccessPhone = tmp.TryGetValue("Phone", out phone);
                    string email = null;
                    bool isSuccessEmail = tmp.TryGetValue("Email", out email);
                    string login = null;
                    bool isSuccessLogin = tmp.TryGetValue("Login", out login);
                    string password = null;
                    bool isSuccessPassword = tmp.TryGetValue("Password", out password);
                    string status = null;
                    bool isSuccessStatus = tmp.TryGetValue("Status", out status);
                    userId = TMSCryptography.Decrypt(userId);
                    if (isSuccessUserId && isSuccessName && isSuccessSurname && isSuccessPhone && isSuccessEmail && isSuccessLogin &&
                        isSuccessPassword && isSuccessStatus)
                    {
                        int userIdNumeric;
                        bool isUserIdANumber = int.TryParse(userId, out userIdNumeric);
                        if (isUserIdANumber)
                        {
                            return RegisterNewUserHelper(name, surname, phone, login, password, email, status, userIdNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters are empty");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/User/RemoveUser
        [HttpPost]
        [ActionName("RemoveUser")]
        public HttpResponseMessage RemoveUser(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string userId = null;
                    bool isSuccessUserId = tmp.TryGetValue("UserId", out userId);
                    string userIdToRemove = null;
                    bool isSuccessUserIdToRemove = tmp.TryGetValue("UserIdToRemove", out userIdToRemove);
                    userId = TMSCryptography.Decrypt(userId);
                    userIdToRemove = TMSCryptography.Decrypt(userIdToRemove);
                    if (isSuccessUserId && isSuccessUserIdToRemove)
                    {
                        int userIdNumeric;
                        bool isUserIdANumber = int.TryParse(userId, out userIdNumeric);
                        int userIdTRNumeric;
                        bool isUserIdTRNumeric = int.TryParse(userIdToRemove, out userIdTRNumeric);
                        if (userIdNumeric == userIdTRNumeric)
                        {
                            return HttpResponseHelper.CreateHttpResponse("error", "You have no rights to remove your own account");
                        }
                        if (isUserIdANumber && isUserIdTRNumeric)
                        {
                            return RemoveUserHelper(userIdNumeric, userIdTRNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters are empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/User/EditUser
        [HttpPost]
        [ActionName("EditUser")]
        public HttpResponseMessage EditUser(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string userId = null;
                    bool isSuccessUserId = tmp.TryGetValue("UserId", out userId);
                    string userTEId = null;
                    bool isSuccessUserTEId = tmp.TryGetValue("UserIdToEdit", out userTEId);
                    string name = null;
                    bool isSuccessName = tmp.TryGetValue("Name", out name);
                    string surname = null;
                    bool isSuccessSurname = tmp.TryGetValue("Surname", out surname);
                    string phone = null;
                    bool isSuccessPhone = tmp.TryGetValue("Phone", out phone);
                    string email = null;
                    bool isSuccessEmail = tmp.TryGetValue("Email", out email);
                    string password = null;
                    bool isSuccessPassword = tmp.TryGetValue("Password", out password);
                    string status = null;
                    bool isSuccessStatus = tmp.TryGetValue("Status", out status);
                    userId = TMSCryptography.Decrypt(userId);
                    userTEId = TMSCryptography.Decrypt(userTEId);
                    if (isSuccessUserId && isSuccessUserTEId && isSuccessName && isSuccessSurname &&
                        isSuccessPhone && isSuccessEmail && isSuccessPassword && isSuccessStatus)
                    {
                        int userIdNumeric;
                        bool isUserIdANumber = int.TryParse(userId, out userIdNumeric);
                        int userIdTENumeric;
                        bool isUserTEIdANumber = int.TryParse(userTEId, out userIdTENumeric);
                        if (isUserIdANumber && isUserTEIdANumber)
                        {
                            return EditUserHelper(userIdNumeric, userIdTENumeric, name, surname, phone, password, email, status);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters are empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }


        private HttpResponseMessage RegisterNewUserHelper(string name, string surname,
            string phone, string login, string password, string email, string status, int userId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var salt = StringGenerator.GenerateString();
                    using (var md5Hash = MD5.Create())
                    {
                        var user = context.Users.FirstOrDefault(u => u.Id == userId);
                        if (user != null)
                        {
                            if (user.Status == "Admin" || user.Status == "Manager")
                            {
                                var passWithSalt = password + salt;
                                var md5Password = StringGenerator.GetMd5Hash(md5Hash, passWithSalt);
                                var newUser = new Users
                                {
                                    Name = name,
                                    Surname = surname,
                                    Phone = phone,
                                    Login = login,
                                    Email = email,
                                    Status = status,
                                    Salt = salt,
                                    Password = md5Password
                                };
                                context.Users.Add(newUser);
                                context.SaveChanges();
                                var result = new TMSUser
                                {
                                    Email = email,
                                    Id = TMSCryptography.Encrypt(newUser.Id + ""),
                                    Login = login,
                                    Name = name,
                                    Surname = surname,
                                    Phone = phone,
                                    Status = status
                                };
                                return HttpResponseHelper.CreateHttpResponse("success", JsonConvert.SerializeObject(result));
                            }
                            return HttpResponseHelper.CreateHttpResponse("error", "You have no permisions to registrate users!");
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "There is no such user!");
                    }
                }

            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage RemoveUserHelper(int userId, int userToRemoveId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var user = context.Users.FirstOrDefault(us => us.Id == userId);
                    if (user != null)
                    {
                        if (user.Status == "Admin" || user.Status == "Manager")
                        {
                            var userTR = context.Users.FirstOrDefault(us => us.Id == userToRemoveId);
                            if (userTR != null)
                            {
                                context.Users.Remove(userTR);
                                context.SaveChanges();
                                return HttpResponseHelper.CreateHttpResponse("success", "");
                            }
                            return HttpResponseHelper.CreateHttpResponse("error", "There is no such user you want to remove!");
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "You have no permision to delete users!");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such user!");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage EditUserHelper(int userId, int userIdTE, string name, string surname,
            string phone, string password, string email, string status)
        {
            try 
            {
                using (var context = new TMSEntities())
                {
                    var user = context.Users.FirstOrDefault(u => u.Id == userId);

                    if (user != null)
                    {
                        if (user.Status == "Admin" || user.Status == "Manager")
                        {
                            var userToEdit = context.Users.FirstOrDefault(u => u.Id == userIdTE);
                            if (userToEdit != null)
                            {
                                using (var md5Hash = MD5.Create())
                                {
                                    var passWithSalt = password + userToEdit.Salt;
                                    var md5Password = StringGenerator.GetMd5Hash(md5Hash, passWithSalt);

                                    userToEdit.Name = name;
                                    userToEdit.Surname = surname;
                                    userToEdit.Phone = phone;
                                    userToEdit.Email = email;
                                    userToEdit.Status = status;
                                    userToEdit.Password = md5Password;
                                    context.SaveChanges();
                                }
                                return HttpResponseHelper.CreateHttpResponse("success", "");
                            }
                            return HttpResponseHelper.CreateHttpResponse("error", "There is no such user you want to edit!");
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "You have no permision to edit users!");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such user!"); 
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }
    }
}
